#include "QuoteLvSubscribe.h"
#include "QuoteLvDef.h"
#include "Tools.h"

void QuoteLvSub_DelItem(QUOTELV_SUBSCRIBE* pSubsc, int aId);

QUOTELV_SUBSCRIBE* QuoteLvSubscribe_New()
{
	QUOTELV_SUBSCRIBE* pSub = (QUOTELV_SUBSCRIBE *)Tools_Malloc(sizeof(QUOTELV_SUBSCRIBE));
	pSub->nCount = 0;
	pSub->pLink = NULL;
	pSub->bLock = FALSE;
	return pSub;
}

void QuoteLvSubscribe_Del(QUOTELV_SUBSCRIBE* pSubsc)
{
	QuoteLvSubscribe_DelAll(pSubsc);
	Tools_Free((void **) &pSubsc);
	
}

QUOTELV_SUBSCRIBE_ITEM* QuoteLvSubscribe_AddItem(QUOTELV_SUBSCRIBE* pSubsc, void( *pCallBack )(void *pCBObj, void *p), void *pCBObj,void* aAsk, void *aRes, char *aData, int aLen, int aId, int aHttpId, char aAskType)
{
	//加锁
	QuoteLvSubscribe_Lock(pSubsc);
	
	QUOTELV_SUBSCRIBE_ITEM *pItem = QuoteLvSubscribe_GetItem(pSubsc,aId);
	
	if (pItem == NULL)
	{
		QUOTELV_SUBSCRIBE_LINK* pNewLink = (QUOTELV_SUBSCRIBE_LINK*) Tools_Malloc(sizeof(QUOTELV_SUBSCRIBE_LINK));
		pNewLink->pSub = (QUOTELV_SUBSCRIBE_ITEM *)Tools_Malloc(sizeof(QUOTELV_SUBSCRIBE_ITEM));
		pNewLink->pSub->Id = aId;
		pNewLink->pSub->pAsk = aAsk;
		pNewLink->pSub->pRes = aRes;
		pNewLink->pSub->pResedData = pCallBack;
		pNewLink->pSub->pCBObj = pCBObj;
		pNewLink->pSub->pData = (char *)Tools_Malloc(aLen);
		pNewLink->pSub->bIsEffective = TRUE;
		pNewLink->pSub->HttpId = aHttpId;
		pNewLink->pSub->HeadType = QUOTE_LV_TYPE_ALL;
		pNewLink->pSub->AskType = aAskType;
		memcpy(pNewLink->pSub->pData,aData,aLen);
		pNewLink->pSub->nLen = aLen;
		pNewLink->pNext = NULL;
		QUOTELV_SUBSCRIBE_LINK* pItemLink = pSubsc->pLink;
		QUOTELV_SUBSCRIBE_LINK* pItemLinkLast = NULL;
		
		while(pItemLink)
		{
			pItemLinkLast = pItemLink;
			pItemLink = pItemLink->pNext;
		}
		
		if (pItemLinkLast)
		{
			pItemLinkLast->pNext = pNewLink;
		}
		else				//第一个
		{
			pSubsc->pLink = pNewLink;
		}
		pSubsc->nCount++;
		
		pItem = pNewLink->pSub;
		
		//printf("\n QuoteLvSubscribe_AddItem nCount = %d", pSubsc->nCount);
	}
	
	//解锁
	QuoteLvSubscribe_UnLock(pSubsc);
	return pItem;
}

void QuoteLvSub_DelItem(QUOTELV_SUBSCRIBE* pSubsc, int aId)
{
	
	QUOTELV_SUBSCRIBE_LINK* pItemLink = pSubsc->pLink;
	QUOTELV_SUBSCRIBE_LINK* pItemLinkLast = NULL;
	
	while(pItemLink)
	{
		if(pItemLink->pSub->Id == aId)
		{
			if (pItemLinkLast == NULL)				//删除的第一个
			{
				pSubsc->pLink = pItemLink->pNext;
			}
			else
			{
				pItemLinkLast->pNext = pItemLink->pNext;
				
			}
			pSubsc->nCount--;
			Tools_Free((void **) &pItemLink->pSub->pData);
			Tools_Free((void **) &pItemLink->pSub);
			Tools_Free((void **) &pItemLink);
			break;
		}
		
		pItemLinkLast = pItemLink;
		pItemLink = pItemLinkLast->pNext;
	}
	
}


void QuoteLvSubscribe_DelAll(QUOTELV_SUBSCRIBE* pSubsc)
{
	//加锁
	QuoteLvSubscribe_Lock(pSubsc);
	QUOTELV_SUBSCRIBE_LINK* pItemLink = pSubsc->pLink;
	QUOTELV_SUBSCRIBE_LINK* pItemLinkNext = NULL;
	
	while(pItemLink)
	{
		
		pItemLinkNext = pItemLink->pNext;
		Tools_Free((void **) &pItemLink->pSub->pData);
		Tools_Free((void **) &pItemLink->pSub);
		Tools_Free((void **) &pItemLink);
		pItemLink = pItemLinkNext;
		
	}
	
	pSubsc->nCount = 0;
	//解锁
	QuoteLvSubscribe_UnLock(pSubsc);
	
}

QUOTELV_SUBSCRIBE_ITEM* QuoteLvSubscribe_GetItem(QUOTELV_SUBSCRIBE* pSubsc, int aId)
{
	QUOTELV_SUBSCRIBE_LINK* pItemLink = pSubsc->pLink;
	QUOTELV_SUBSCRIBE_LINK* pItemLinkNext = NULL;
	
	while(pItemLink)
	{
		
		if(pItemLink->pSub->Id == aId && pItemLink->pSub->bIsEffective)
		{
			return pItemLink->pSub;
		}
		
		pItemLink = pItemLink->pNext;
	}
	
	return NULL;
}

QUOTELV_SUBSCRIBE_ITEM* QuoteLvSubscribe_GetHttpItem(QUOTELV_SUBSCRIBE* pSubsc, int aHttpId)
{
	QUOTELV_SUBSCRIBE_LINK* pItemLink = pSubsc->pLink;
	QUOTELV_SUBSCRIBE_LINK* pItemLinkNext = NULL;
	
	while(pItemLink)
	{
		
		if(pItemLink->pSub->HttpId == aHttpId && pItemLink->pSub->bIsEffective)
		{
			return pItemLink->pSub;
		}
		
		pItemLink = pItemLink->pNext;
	}
	
	return NULL;
}

QUOTELV_SUBSCRIBE_ITEM* QuoteLvSubscribe_GetIndexItem(QUOTELV_SUBSCRIBE* pSubsc, int aIndex)
{
	
	if (aIndex < 0 || aIndex >= pSubsc->nCount)
	{
		return NULL;
	}
	
	QUOTELV_SUBSCRIBE_LINK* pItemLink = pSubsc->pLink;
	QUOTELV_SUBSCRIBE_LINK* pItemLinkNext = NULL;
	int nNum = 0;
	
	while(pItemLink)
	{
		
		if(aIndex == nNum && pItemLink->pSub->bIsEffective)
		{
			return pItemLink->pSub;
		}
		
		pItemLink = pItemLink->pNext;
		nNum++;
	}
	
	return NULL;
}

void QuoteLvSubscribe_ClearInvalidItem(QUOTELV_SUBSCRIBE* pSubsc)
{
	//加锁
	QuoteLvSubscribe_Lock(pSubsc);
	
	QUOTELV_SUBSCRIBE_LINK* pItemLink = pSubsc->pLink;
	QUOTELV_SUBSCRIBE_LINK* pItemLinkNext = NULL;
	
	while(pItemLink)
	{
		pItemLinkNext = pItemLink->pNext;
		
		if (!pItemLink->pSub->bIsEffective)
		{
			QuoteLvSub_DelItem(pSubsc,pItemLink->pSub->Id);
		}
		
		pItemLink = pItemLinkNext;
	}
	
	
	//解锁
	QuoteLvSubscribe_UnLock(pSubsc);
	
	//printf("\n QuoteLvSubscribe_ClearInvalidItem nCount = %d", pSubsc->nCount);
}

void QuoteLvSubscribe_Lock(QUOTELV_SUBSCRIBE* pSubsc)
{
	while (pSubsc->bLock) {
		SLEEP(100);
	}
	pSubsc->bLock = TRUE;
}


void QuoteLvSubscribe_UnLock(QUOTELV_SUBSCRIBE* pSubsc)
{
	pSubsc->bLock = FALSE;
}